//
// StoreNuke.Net -  http://www.storenuke.net
// Copyright (c) 2005
// by Robert J Collins ( info@storenuke.net ) of WillowTree Software, Inc. ( http://www.willowtreesoftware.com )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using System.Collections;
using System.IO;
using System.Text.RegularExpressions;
using ICSharpCode.SharpZipLib.Zip;

namespace StoreNuke.StarterKit.Commerce.Admin.Skin
{
	/// <summary>
	/// Summary description for Skins.
	/// </summary>
	public class Skins
	{
		//protected static string ccsPath = "";
		protected static string skinHTML = "";
		private static ArrayList m_HTMLPatterns = new ArrayList();
		protected static string SkinPath = "skins";

		public static string UploadSkin(string RootPath, string SkinRoot, string SkinName, Stream objInputStream) 
		{ 
			ZipInputStream objZipInputStream = new ZipInputStream(objInputStream); 
			ZipEntry objZipEntry; 
			string strExtension; 
			string strFileName = ""; 
			FileStream objFileStream; 
			int intSize = 2048; 
			byte[] arrData = new byte[2048]; 
			string strMessage = ""; 
			ArrayList arrSkinFiles = new ArrayList(); 
			strMessage += FormatMessage("Begin processing zip file" + SkinName); 
			objZipEntry = objZipInputStream.GetNextEntry(); 
			skinHTML = "";
			while (!(objZipEntry == null)) 
			{ 
				if (!(objZipEntry.IsDirectory)) 
				{ 
					strExtension = objZipEntry.Name.Substring(objZipEntry.Name.LastIndexOf(".") + 1); 
					//if (InStr(1, ",ASCX,HTM,HTML,CSS,SWF," + Global.HostSettings("FileExtensions").ToString.ToUpper, "," + strExtension.ToUpper()) != 0) 
					if (InStringCheck(strExtension.ToUpper(), "XML,ASCX,HTM,HTML,CSS,SWF,JPG,PNG,GIF,TXT,ZIP".Split(",".ToCharArray()))) 
					{ 

						strFileName = RootPath + SkinRoot + SkinName + "\\" + objZipEntry.Name; 
						//strFileName.Replace(@"\\",@"\");
						if (!(Directory.Exists(Path.GetDirectoryName(strFileName)))) 
						{ 
							strMessage += FormatMessage("Creating directory: " + Path.GetDirectoryName(strFileName)); 
							Directory.CreateDirectory(Path.GetDirectoryName(strFileName)); 
						} 
						if (File.Exists(strFileName)) 
						{ 
							File.SetAttributes(strFileName, FileAttributes.Normal); 
							File.Delete(strFileName); 
						} 
						objFileStream = File.Create(strFileName); 
						strMessage += FormatMessage("Writing file: "  + Path.GetFileName(strFileName)); 
						intSize = objZipInputStream.Read(arrData, 0, arrData.Length); 
						while (intSize > 0) 
						{ 
							objFileStream.Write(arrData, 0, intSize); 
							intSize = objZipInputStream.Read(arrData, 0, arrData.Length); 
						} 
						objFileStream.Close(); 
						if (Path.GetExtension(strFileName) == ".htm" || Path.GetExtension(strFileName) == ".html" || Path.GetExtension(strFileName) == ".ascx" || Path.GetExtension(strFileName) == ".css") 
						{ 
							arrSkinFiles.Add(strFileName); 
						} 
					} 
					else 
					{ 
						strMessage += FormatMessage("Error processing file: " + objZipEntry.Name + " is a restricted file type. Valid file types include ( XML,ASCX,HTM,HTML,CSS,SWF,JGP,PNG,GIF,TXT,ZIP ). Please contact your hosting provider if you need to upload a file type which is not supported."); 
					} 
				} 
				objZipEntry = objZipInputStream.GetNextEntry(); 

				if(strFileName.IndexOf(".htm") > -1){
				CreateSkin(strFileName);
				}

			} 
			strMessage += FormatMessage("End processing zip file: " + SkinName + ".zip"); 
			objZipInputStream.Close(); 

			return strMessage; 
		}

		public static bool InStringCheck(string comp, string[] ext)
		{
			foreach(string singleExt in ext)
			{
				if(comp.IndexOf(singleExt) > -1)
					return true;
			}
			return false;
		}

		public static string FormatMessage(string str)
		{
			return str + "<br><br>";
		}

		public static bool CreateSkin(string filePath)
		{
			// Load the skin html file
			StreamReader r = File.OpenText(filePath);
			skinHTML += r.ReadToEnd();
			r.Close();

			//Prep new file name/path
			filePath = filePath.Substring(0,filePath.LastIndexOf(".")) + ".ascx";

			//Replace Tokens
			//skinContent = skinContent + "<B>This is a Test</b>";
			ReplaceTokens(filePath);

			//Save File Back As Copy with .ascx
			StreamWriter wr = new StreamWriter(filePath);
			wr.Write(skinHTML);
			wr.Close();

			return true;
		}

		public static ArrayList HTMLList 
		{ 
			get 
			{ 
				if (m_HTMLPatterns.Count == 0) 
				{ 
					string[] arrPattern =	{"(?<tag><head[^>]*?\\sprofile\\s*=\\s*\")(?!https://|http://|\\\\|[~/])(?<content>[^\"]*)(?<endtag>\"[^>]*>)", 
											"(?<tag><object[^>]*?\\s(?:codebase|data|usemap)\\s*=\\s*\")(?!https://|http://|\\\\|[~/])(?<content>[^\"]*)(?<endtag>\"[^>]*>)", 
											"(?<tag><img[^>]*?\\s(?:src|longdesc|usemap)\\s*=\\s*\")(?!https://|http://|\\\\|[~/])(?<content>[^\"]*)(?<endtag>\"[^>]*>)", 
											"(?<tag><input[^>]*?\\s(?:src|usemap)\\s*=\\s*\")(?!https://|http://|\\\\|[~/])(?<content>[^\"]*)(?<endtag>\"[^>]*>)", 
											"(?<tag><iframe[^>]*?\\s(?:src|longdesc)\\s*=\\s*\")(?!https://|http://|\\\\|[~/])(?<content>[^\"]*)(?<endtag>\"[^>]*>)", 
											"(?<tag><(?:td|th|table|body)[^>]*?\\sbackground\\s*=\\s*\")(?!https://|http://|\\\\|[~/])(?<content>[^\"]*)(?<endtag>\"[^>]*>)", 
											"(?<tag><(?:script|bgsound|embed|xml|frame)[^>]*?\\ssrc\\s*=\\s*\")(?!https://|http://|\\\\|[~/])(?<content>[^\"]*)(?<endtag>\"[^>]*>)", 
											"(?<tag><(?:base|link|a|area)[^>]*?\\shref\\s*=\\s*\")(?!https://|http://|\\\\|[~/]|javascript:|mailto:)(?<content>[^\"]*)(?<endtag>\"[^>]*>)", 
											"(?<tag><(?:blockquote|ins|del|q)[^>]*?\\scite\\s*=\\s*\")(?!https://|http://|\\\\|[~/])(?<content>[^\"]*)(?<endtag>\"[^>]*>)", 
											"(?<tag><(?:param\\s+name\\s*=\\s*\"(?:movie|src|base)\")[^>]*?\\svalue\\s*=\\s*\")(?!https://|http://|\\\\|[~/])(?<content>[^\"]*)(?<endtag>\"[^>]*>)", 
											"(?<tag><embed[^>]*?\\s(?:src)\\s*=\\s*\")(?!https://|http://|\\\\|[~/])(?<content>[^\"]*)(?<endtag>\"[^>]*>)"}; 
			
				for (int i = 0; i <= arrPattern.GetLength(0) - 1; i++) 
				{ 
					Regex re = new Regex(arrPattern[i], RegexOptions.Multiline | RegexOptions.IgnoreCase); 
					m_HTMLPatterns.Add(re); 
				} 
				m_HTMLPatterns.TrimToSize(); 
			} 
				return m_HTMLPatterns; 
			} 
		}

		public static string Parse(ArrayList RegexList) 
		{ 
			string m_Messages = ""; 
			MatchEvaluator myEvaluator = new MatchEvaluator(MatchHandler);
			for (int i = 0; i <= RegexList.Count - 1; i++) 
			{ 
				skinHTML = ((Regex)(RegexList[i])).Replace(skinHTML, myEvaluator); 
			} 
			return m_Messages; 
		}

		private static string MatchHandler(Match m) 
		{ 
			string strOldTag = m.Groups["tag"].Value + m.Groups["content"].Value + m.Groups["endtag"].Value; 
			string strNewTag = strOldTag; 
			if(strNewTag.IndexOf(SkinPath) == -1)
			{
				strNewTag = m.Groups["tag"].Value + SkinPath + m.Groups["content"].Value + m.Groups["endtag"].Value;
			}

			return strNewTag; 
		}

		public static void ReplaceTokens(string filePath)
		{
			string skinName = filePath.Substring(filePath.LastIndexOf("\\") + 1);
			skinName = skinName.Substring(0,skinName.IndexOf("."));
			string styleSheet = "<link rel=\"stylesheet\" type=\"text/css\" href=\"" + filePath.Substring(filePath.IndexOf("Skins")).Replace(".ascx",".css").Replace(@"\","/") + "\" />\n";
			string header = "";

			string pDirective = "<%@ Control Language=\"c#\" AutoEventWireup=\"false\" Codebehind=\"Skin.ascx.cs\" Inherits=\"StoreNuke.StarterKit.Commerce.Skin\"%>\n";

			skinHTML = skinHTML.Replace("[CONTENT]","<asp:placeholder id=\"SkinPlaceHolder\" runat=\"server\"></asp:placeholder>");

			string[] arrPattern = {"[MENU]|Menu|_Menu.ascx","[CART]|CartButton|_CartButton.ascx","[LOGO]|Logo|_Logo.ascx","[SEARCH]|Search|_Search.ascx",
									"[SIGNIN]|SigninButton|_SigninButton.ascx","[ACCOUNT]|Account|_Account.ascx","[TERMS]|Terms|_Terms.ascx",
									"[PRIVACY]|Privacy|_Privacy.ascx","[COPYRIGHT]|Copyright|_Copyright.ascx","[CURRENTDATE]|CurrentDate|_CurrentDate.ascx",
									"[HELP]|Help|_Help.ascx","[PROFILE]|ProfileButton|_ProfileButton.ascx"};

			for (int i = 0; i <= arrPattern.GetLength(0) - 1; i++) 
			{
				string[] arrParts = arrPattern[i].Split("|".ToCharArray());
				if(skinHTML.IndexOf(arrParts[0]) != -1)
				{
					skinHTML = skinHTML.Replace(arrParts[0],"<StoreNukeCommerce:" + arrParts[1] + " id=\"" + arrParts[1] + "1\" runat=\"server\" />");
					header = header + "<%@ Register TagPrefix=\"StoreNukeCommerce\" TagName=\"" + arrParts[1] + "\" Src=\"~/Controls/" + arrParts[2] + "\" %>\n"; 
				}

			}

			skinHTML = pDirective + header + styleSheet + skinHTML;

			SkinPath = "Skins/" + skinName + "/";
			Skins.Parse(HTMLList);
		}
	}
}
